/************************************************************
   Copyright 2008 Abhinav Pobbati

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*************************************************************/

#pragma once

#include "Havok4Xna/Common/Base/Types/HkContactPoint.h"

#pragma unmanaged
#include <Physics/Dynamics/Constraint/hkpConstraintData.h>
#include <Physics/ConstraintSolver/Solve/hkpSolverResults.h>
#include <Physics/ConstraintSolver/Constraint/Motor/hkpMotorConstraintInfo.h>
#include <Physics/ConstraintSolver/Constraint/Atom/hkpConstraintAtom.h>
//#include <Physics/ConstraintSolver/Constraint/Chain/hkpPoweredChainSolverUtil.h>
//#include <Physics/ConstraintSolver/Constraint/Chain/hkpChainConstraintInfo.h>
#include <Physics/ConstraintSolver/Constraint/hkpConstraintQueryIn.h>
#include <Physics/ConstraintSolver/Constraint/hkpConstraintQueryOut.h>
//#include <Physics/ConstraintSolver/Jacobian/hkpJacobianSchema.h>
#include <Physics/ConstraintSolver/Simplex/hkpSimplexSolver.h>
#include <Physics/ConstraintSolver/Vehiclefriction/hkpVehicleFrictionSolver.h>
//#include <Physics/ConstraintSolver/Constraint/Bilateral/hkp1dBilateralConstraintInfo.h>
#include <Physics/ConstraintSolver/SimpleConstraints/hkpSimpleConstraintUtil.h>
#include <Physics/ConstraintSolver/Solve/hkpSolverInfo.h>
#pragma managed

using System::Runtime::InteropServices::OutAttribute;
using System::IntPtr;

namespace Havok4Xna {
	ref class HkVector4;
	ref class HkRotation;
	ref class HkTransform;
	ref class HkMatrix3;
	ref class HkStepInfo;

	namespace Physics {
		namespace Dynamics {
			ref class HkpConstraintMotor;
			ref class HkpConstraintData;
			ref class HkpConstraintInfo;
			ref class HkpConstraintInstance;
		}
	}
}
using namespace Havok4Xna;
using namespace Havok4Xna::Physics::Dynamics;

namespace Havok4Xna {
	namespace Physics {
		namespace ConstraintSolver {
			public ref class HkpSolverInfo sealed {
			public:
				enum class DeactivationClass : int {
					Invalid = hkpSolverInfo::DEACTIVATION_CLASS_INVALID,
					Off = hkpSolverInfo::DEACTIVATION_CLASS_OFF,
					Low = hkpSolverInfo::DEACTIVATION_CLASS_LOW,
					Medium = hkpSolverInfo::DEACTIVATION_CLASS_MEDIUM,
					High = hkpSolverInfo::DEACTIVATION_CLASS_HIGH,
					Aggressive = hkpSolverInfo::DEACTIVATION_CLASS_AGGRESSIVE,
					End = hkpSolverInfo::DEACTIVATION_CLASSES_END
				};

				ref class DeactivationInfo sealed {
				public:
					DeactivationInfo();

					DECLARE_PROPERTY_GETSET(float, LinearVelocityThresholdInv)
					DECLARE_PROPERTY_GETSET(float, AngularVelocityThresholdInv)
					DECLARE_PROPERTY_GETSET(float, SlowObjectVelocityMultiplier)
					DECLARE_PROPERTY_GETSET(float, RelativeSteepVelocityThreshold)
					DECLARE_PROPERTY_GETSET(float, MaxDistSqrd0)
					DECLARE_PROPERTY_GETSET(float, MaxDistSqrd1)
					DECLARE_PROPERTY_GETSET(float, MaxRotSqrd0)
					DECLARE_PROPERTY_GETSET(float, MaxRotSqrd1)

				internal:
					HK_CLASS_INTERNALS(DeactivationInfo, hkpSolverInfo::DeactivationInfo)
				};

				DECLARE_PROPERTY_GETSET(float, One)
				DECLARE_PROPERTY_GETSET(float, Tau)
				DECLARE_PROPERTY_GETSET(float, Damping)
				DECLARE_PROPERTY_GETSET(float, FrictionTau)
				DECLARE_COMPLEX_PROPERTY_GETSET(HkVector4, GlobalAccelerationPerSubStep)
				DECLARE_COMPLEX_PROPERTY_GETSET(HkVector4, GlobalAccelerationPerStep)
				DECLARE_COMPLEX_PROPERTY_GETSET(HkVector4, IntegrateVelocityFactor)
				DECLARE_COMPLEX_PROPERTY_GETSET(HkVector4, InvIntegrateVelocityFactor)
				DECLARE_PROPERTY_GETSET(float, DampDivTau)
				DECLARE_PROPERTY_GETSET(float, TauDivDamp)
				DECLARE_PROPERTY_GETSET(float, DampDivFrictionTau)
				DECLARE_PROPERTY_GETSET(float, FrictionTauDivDamp)
				DECLARE_PROPERTY_GETSET(float, ContactRestingVelocity)
				/*DECLARE_COMPLEX_PROPERTY_GETSET(DeactivationInfo, */
				DECLARE_PROPERTY_GETSET(float, DeltaTime)
				DECLARE_PROPERTY_GETSET(float, InvDeltaTime)
				DECLARE_PROPERTY_GETSET(int, NumSteps)
				DECLARE_PROPERTY_GETSET(int, NumMicroSteps)
				DECLARE_PROPERTY_GETSET(float, InvNumMicroSteps)
				DECLARE_PROPERTY_GETSET(float, InvNumSteps)
				DECLARE_PROPERTY_GETSET(bool, ForceCoherentConstraintOrderingInSolver)
				DECLARE_PROPERTY_GETSET(hkUint8, DeactivationNumInactiveFramesSelectFlag0)
				DECLARE_PROPERTY_GETSET(hkUint8, DeactivationNumInactiveFramesSelectFlag1)
				DECLARE_PROPERTY_GETSET(hkUint8, DeactivationIntegrateCounter)

				HkpSolverInfo();
				void SetTauAndDamping(float tau, float damping);
				void IncrementDeactivationFlags();

			internal:
				HK_CLASS_INTERNALS(HkpSolverInfo, hkpSolverInfo)
			};

			public ref class Hkp1dBilateralConstraintStatus : public INativeReference {
			public:
				Hkp1dBilateralConstraintStatus();

				DECLARE_PROPERTY_GETSET(float, VirtualMass)

			internal:
				HK_CLASS_INTERNALS(Hkp1dBilateralConstraintStatus, hkp1dBilateralConstraintStatus)
			};

			public ref class Hkp1dConstraintMotorInfo : public INativeReference {
			public:
				Hkp1dConstraintMotorInfo();

				DECLARE_PROPERTY_GETSET(float, TargetPosition)
				DECLARE_PROPERTY_GETSET(float, TargetVelocity)
				DECLARE_PROPERTY_GETSET(float, MaxForce)
				DECLARE_PROPERTY_GETSET(float, MinForce)
				DECLARE_PROPERTY_GETSET(float, Tau)
				DECLARE_PROPERTY_GETSET(float, Damping)

			internal:
				HK_CLASS_INTERNALS(Hkp1dConstraintMotorInfo, hkp1dConstraintMotorInfo)
			};

			public ref class HkpConstraintAtom : public INativeReference {
			public:
				enum class AtomType : int {
					Invalid = hkpConstraintAtom::TYPE_INVALID,
					Bridge = hkpConstraintAtom::TYPE_BRIDGE,
					SetLocalTransforms = hkpConstraintAtom::TYPE_SET_LOCAL_TRANSFORMS,
					SetLocalTranslations = hkpConstraintAtom::TYPE_SET_LOCAL_TRANSLATIONS,
					SetLocalRotations = hkpConstraintAtom::TYPE_SET_LOCAL_ROTATIONS,
					BallSocket = hkpConstraintAtom::TYPE_BALL_SOCKET,
					StiffSpring = hkpConstraintAtom::TYPE_STIFF_SPRING,
					Lin = hkpConstraintAtom::TYPE_LIN,
					LinSoft = hkpConstraintAtom::TYPE_LIN_SOFT,
					LinLimit = hkpConstraintAtom::TYPE_LIN_LIMIT,
					LinFriction = hkpConstraintAtom::TYPE_LIN_FRICTION,
					LinMotor = hkpConstraintAtom::TYPE_LIN_MOTOR,
					_2DAng = hkpConstraintAtom::TYPE_2D_ANG,
					Ang = hkpConstraintAtom::TYPE_ANG,
					AngLimit = hkpConstraintAtom::TYPE_ANG_LIMIT,
					TwistLimit = hkpConstraintAtom::TYPE_CONE_LIMIT,
					ConeLimit = hkpConstraintAtom::TYPE_CONE_LIMIT,
					AngFriction = hkpConstraintAtom::TYPE_ANG_FRICTION,
					AngMotor = hkpConstraintAtom::TYPE_ANG_MOTOR,
					RagDollMotor = hkpConstraintAtom::TYPE_RAGDOLL_MOTOR,
					Pulley = hkpConstraintAtom::TYPE_PULLEY,
					OverwritePivot = hkpConstraintAtom::TYPE_OVERWRITE_PIVOT,
					Contact = hkpConstraintAtom::TYPE_CONTACT,
					ModifierSoftContact = hkpConstraintAtom::TYPE_MODIFIER_SOFT_CONTACT,
					ModifierMassChanger = hkpConstraintAtom::TYPE_MODIFIER_MASS_CHANGER,
					ModifierViscousSurface = hkpConstraintAtom::TYPE_MODIFIER_VISCOUS_SURFACE,
					ModifierMovingSurface = hkpConstraintAtom::TYPE_MODIFIER_MOVING_SURFACE,
					ModifierIgnoreConstraint = hkpConstraintAtom::TYPE_MODIFIER_IGNORE_CONSTRAINT
				};

				// flag indicating whether this constraint needs some special callback treatment
				// those flags can be combined
				enum class CallbackRequest : int {
					None = hkpConstraintAtom::CALLBACK_REQUEST_NONE,
					NewContactPoint = hkpConstraintAtom::CALLBACK_REQUEST_NEW_CONTACT_POINT,
					SetupPPUOnly = hkpConstraintAtom::CALLBACK_REQUEST_SETUP_PPU_ONLY,
					SetupCallback = hkpConstraintAtom::CALLBACK_REQUEST_SETUP_CALLBACK
				};

				DECLARE_PROPERTY_GET(AtomType, Type);
				DECLARE_PROPERTY_GET(int, IsModifierType);

			internal:
				HK_CLASS_INTERNALS(HkpConstraintAtom, hkpConstraintAtom)
			};


			public ref class Hkp2dAngConstraintAtom : public HkpConstraintAtom {
			public:
				Hkp2dAngConstraintAtom();

				DECLARE_PROPERTY_GETSET(System::Byte, FreeRotationAxis);

			internal:
				HK_DERIVED_CLASS_INTERNALS(Hkp2dAngConstraintAtom, hkp2dAngConstraintAtom, HkpConstraintAtom)
			};


			public ref class HkpAngConstraintAtom : public HkpConstraintAtom {
			public:
				HkpAngConstraintAtom();

				DECLARE_PROPERTY_GETSET(System::Byte, FirstConstrainedAxis);
				DECLARE_PROPERTY_GETSET(System::Byte, NumConstrainedAxes);

			internal:
				HK_DERIVED_CLASS_INTERNALS(HkpAngConstraintAtom, hkpAngConstraintAtom, HkpConstraintAtom)
			};

			public ref class HkpAngFrictionConstraintAtom : public HkpConstraintAtom {
			public:
				HkpAngFrictionConstraintAtom();

				DECLARE_PROPERTY_GETSET(System::Byte, IsEnabled);
				DECLARE_PROPERTY_GETSET(System::Byte, FirstFrictionAxis);
				DECLARE_PROPERTY_GETSET(System::Byte, NumFrictionAxes);
				DECLARE_PROPERTY_GETSET(float, MaxFrictionTorque);

			internal:
				HK_DERIVED_CLASS_INTERNALS(HkpAngFrictionConstraintAtom, hkpAngFrictionConstraintAtom, HkpConstraintAtom)
			};

			public ref class HkpAngLimitConstraintAtom : public HkpConstraintAtom {
			public:
				HkpAngLimitConstraintAtom();

				DECLARE_PROPERTY_GETSET(System::Byte, IsEnabled);
				DECLARE_PROPERTY_GETSET(System::Byte, LimitAxis);
				DECLARE_PROPERTY_GETSET(float, MinAngle);
				DECLARE_PROPERTY_GETSET(float, MaxAngle);
				DECLARE_PROPERTY_GETSET(float, AngularLimitsTauFactor);

			internal:
				HK_DERIVED_CLASS_INTERNALS(HkpAngLimitConstraintAtom, hkpAngLimitConstraintAtom, HkpConstraintAtom)
			};

			public ref class HkpAngMotorConstraintAtom : public HkpConstraintAtom {
			public:
				HkpAngMotorConstraintAtom();
				DECLARE_PROPERTY_GETSET(bool, IsEnabled);
				DECLARE_PROPERTY_GETSET(System::Byte, MotorAxis);
				DECLARE_PROPERTY_GETSET(System::Int16, InitializedOffset);
				DECLARE_PROPERTY_GETSET(System::Int16, PreviousTargetAngleOffset);
				DECLARE_PROPERTY_GETSET(System::Int16, CorrespondingAngLimitSolverResultOffset);
				DECLARE_PROPERTY_GETSET(float, TargetAngle);

			internal:
				HK_DERIVED_CLASS_INTERNALS(HkpAngMotorConstraintAtom, hkpAngMotorConstraintAtom, HkpConstraintAtom)
			};

			public ref class HkpBallSocketConstraintAtom : public HkpConstraintAtom {
			public:
				HkpBallSocketConstraintAtom();
				HkpConstraintAtom ^Next();
				void AddToConstraintInfo([Out] HkpConstraintInfo ^infoOut);

				DECLARE_PROPERTY_GET(int, NumSolverResults);

			internal:
				HK_DERIVED_CLASS_INTERNALS(HkpBallSocketConstraintAtom, hkpBallSocketConstraintAtom, HkpConstraintAtom)
			};

			public ref class HkpBridgeConstraintAtom : public HkpConstraintAtom {
			public:
				HkpBridgeConstraintAtom();
				void Init(HkpConstraintData ^constraintData);
				HkpConstraintAtom ^Next();

				DECLARE_PROPERTY_GET(int, NumSolverResults);
				DECLARE_COMPLEX_PROPERTY_GETSET(HkpConstraintData, ConstraintData);

			internal:
				HK_DERIVED_CLASS_INTERNALS(HkpBridgeConstraintAtom, hkpBridgeConstraintAtom, HkpConstraintAtom)
			};

			public ref class HkpBridgeAtoms sealed : public INativeReference {
			public:
				HkpBridgeAtoms();

				DECLARE_COMPLEX_PROPERTY_GETSET(HkpBridgeConstraintAtom, BridgeAtom);
				DECLARE_PROPERTY_GET(int, SizeOfAllAtoms);

			internal:
				HK_CLASS_INTERNALS(HkpBridgeAtoms, hkpBridgeAtoms)
			};

			public ref class HkpSimpleContactConstraintAtom : public HkpConstraintAtom {
			public:
				HkpSimpleContactConstraintAtom();
				// TODO:

			internal:
				HK_DERIVED_CLASS_INTERNALS(HkpSimpleContactConstraintAtom, hkpSimpleContactConstraintAtom, HkpConstraintAtom)
			};

			public ref class HkpConeLimitConstraintAtom : public HkpConstraintAtom {
			public:
				enum class MeasurementMode : System::Byte {
					ZeroWhenVectorsAligned = hkpConeLimitConstraintAtom::ZERO_WHEN_VECTORS_ALIGNED,
					ZeroWhenVectorsPerpendicular = hkpConeLimitConstraintAtom::ZERO_WHEN_VECTORS_PERPENDICULAR
				};

				HkpConeLimitConstraintAtom();
				DECLARE_PROPERTY_GETSET(System::Byte, IsEnabled);
				DECLARE_PROPERTY_GETSET(System::Byte, TwistAxisInA);
				DECLARE_PROPERTY_GETSET(System::Byte, RefAxisInB);
				DECLARE_PROPERTY_GETSET(System::Byte, MemOffsetToAngleOffset);
				DECLARE_PROPERTY_GETSET(float, MinAngle);
				DECLARE_PROPERTY_GETSET(float, MaxAngle);
				DECLARE_PROPERTY_GETSET(float, AngularLimitsTauFactor);
				DECLARE_PROPERTY_GETSET(MeasurementMode, AngleMeasurementMode);

			internal:
				HK_DERIVED_CLASS_INTERNALS(HkpConeLimitConstraintAtom, hkpConeLimitConstraintAtom, HkpConstraintAtom)
			};

			public ref class HkpConstraintQueryStepInfo : public INativeReference {
			public:
				HkpConstraintQueryStepInfo();

				DECLARE_PROPERTY_GETSET(float, SubstepInvDeltaTime);
				DECLARE_PROPERTY_GETSET(float, SubstepDeltaTime);
				DECLARE_PROPERTY_GETSET(float, MicroStepDeltaTime);
				DECLARE_PROPERTY_GETSET(float, FrameDeltaTime);
				DECLARE_PROPERTY_GETSET(float, FrameInvDeltaTime);
				DECLARE_PROPERTY_GETSET(float, InvNumSteps);
				DECLARE_PROPERTY_GETSET(float, InvNumStepsTimesMicroSteps);
				DECLARE_PROPERTY_GETSET(float, RhsFactor);
				DECLARE_PROPERTY_GETSET(float, VirtMassFactor);
				DECLARE_PROPERTY_GETSET(float, FrictionRhsFactor);

			internal:
				HK_CLASS_INTERNALS(HkpConstraintQueryStepInfo, hkpConstraintQueryStepInfo)
			};

			public ref class HkpSolverResults : public INativeReference {
			public:
				DECLARE_PROPERTY_GET(float, ImpulseApplied);

			internal:
				HK_CLASS_INTERNALS(HkpSolverResults, hkpSolverResults)
			};

			public ref class HkpConstraintMotorInput : public Hkp1dBilateralConstraintStatus {
			public:
				HkpConstraintMotorInput();
				DECLARE_COMPLEX_PROPERTY_GET(HkpConstraintQueryStepInfo, StepInfo);
				DECLARE_COMPLEX_PROPERTY_GETSET(HkpSolverResults, LastResults);
				DECLARE_PROPERTY_GETSET(float, DeltaTarget);
				DECLARE_PROPERTY_GETSET(float, PositionError);

			internal:
				HK_DERIVED_CLASS_INTERNALS(HkpConstraintMotorInput, hkpConstraintMotorInput, Hkp1dBilateralConstraintStatus)
			};

			public ref class HkpConstraintMotorOutput : public Hkp1dConstraintMotorInfo {
				
			};

			ref class HkpVelocityAccumulator;

			public ref class HkpConstraintQueryIn : public HkpConstraintQueryStepInfo {
			public:
				HkpConstraintQueryIn();
				DECLARE_COMPLEX_PROPERTY_GETSET(HkpVelocityAccumulator, BodyA);
				DECLARE_COMPLEX_PROPERTY_GETSET(HkpVelocityAccumulator, BodyB);
				DECLARE_COMPLEX_PROPERTY_GETSET(HkTransform, TransformA);
				DECLARE_COMPLEX_PROPERTY_GETSET(HkTransform, TransformB);
				DECLARE_PROPERTY_GETSET(float, Tau);
				DECLARE_PROPERTY_GETSET(float, Damping);
				DECLARE_COMPLEX_PROPERTY_GETSET(HkpConstraintInstance, ConstraintInstance);
				DECLARE_PROPERTY_GETSET(IntPtr, ConstraintRuntime);
				DECLARE_PROPERTY_GETSET(hkUint32, AccumulatorAIndex);
				DECLARE_PROPERTY_GETSET(hkUint32, AccumulatorBIndex);

				void Set(HkpSolverInfo ^si, HkStepInfo ^stepInfo);

			internal:
				HK_DERIVED_CLASS_INTERNALS(HkpConstraintQueryIn, hkpConstraintQueryIn, HkpConstraintQueryStepInfo)
			};

			public ref class HkpConstraintQueryOut {
			internal:
				HK_CLASS_INTERNALS(HkpConstraintQueryOut, hkpConstraintQueryOut)
			};

			public ref class HkpContactPointProperties : public HkpSolverResults/*, public HkContactPointMaterial*/ {
			internal:
				HK_DERIVED_CLASS_INTERNALS(HkpContactPointProperties, hkpContactPointProperties, HkpSolverResults)
			};

			public ref class HkpLinConstraintAtom : public HkpConstraintAtom {
			public:
				HkpLinConstraintAtom();
				DECLARE_PROPERTY_GETSET(System::Byte, AxisIndex);

			internal:
				HK_DERIVED_CLASS_INTERNALS(HkpLinConstraintAtom, hkpLinConstraintAtom, HkpConstraintAtom)
			};

			public ref class HkpLinFrictionConstraintAtom : public HkpConstraintAtom {
			public:
				HkpLinFrictionConstraintAtom();
				DECLARE_PROPERTY_GETSET(System::Byte, IsEnabled);
				DECLARE_PROPERTY_GETSET(System::Byte, FrictionAxis);
				DECLARE_PROPERTY_GETSET(float, MaxFrictionForce);

			internal:
				HK_DERIVED_CLASS_INTERNALS(HkpLinFrictionConstraintAtom, hkpLinFrictionConstraintAtom, HkpConstraintAtom)
			};

			public ref class HkpLinLimitConstraintAtom : public HkpConstraintAtom {
			public:
				HkpLinLimitConstraintAtom();
				DECLARE_PROPERTY_GETSET(System::Byte, AxisIndex);
				DECLARE_PROPERTY_GETSET(float, Min);
				DECLARE_PROPERTY_GETSET(float, Max);

			internal:
				HK_DERIVED_CLASS_INTERNALS(HkpLinLimitConstraintAtom, hkpLinLimitConstraintAtom, HkpConstraintAtom)
			};

			public ref class HkpLinMotorConstraintAtom : public HkpConstraintAtom {
			public:
				HkpLinMotorConstraintAtom();
				DECLARE_PROPERTY_GETSET(bool, IsEnabled);
				DECLARE_PROPERTY_GETSET(System::Byte, MotorAxis);
				DECLARE_PROPERTY_GETSET(hkInt16, InitializedOffset);
				DECLARE_PROPERTY_GETSET(hkInt16, PreviousTargetPositionOffset);
				DECLARE_PROPERTY_GETSET(float, TargetPosition);

			internal:
				HK_DERIVED_CLASS_INTERNALS(HkpLinMotorConstraintAtom, hkpLinMotorConstraintAtom, HkpConstraintAtom)
			};

			public ref class HkpLinSoftConstraintAtom : public HkpConstraintAtom {
			public:
				HkpLinSoftConstraintAtom();
				DECLARE_PROPERTY_GETSET(System::Byte, AxisIndex);
				DECLARE_PROPERTY_GETSET(float, Tau);
				DECLARE_PROPERTY_GETSET(float, Damping);

			internal:
				HK_DERIVED_CLASS_INTERNALS(HkpLinSoftConstraintAtom, hkpLinSoftConstraintAtom, HkpConstraintAtom)
			};

			public ref class HkpPulleyConstraintAtom : public HkpConstraintAtom {
			public:
				HkpPulleyConstraintAtom();
				DECLARE_COMPLEX_PROPERTY_GETSET(HkVector4, FixedPivotAinWorld);
				DECLARE_COMPLEX_PROPERTY_GETSET(HkVector4, FixedPivotBinWorld);
				DECLARE_PROPERTY_GETSET(float, RopeLength);
				DECLARE_PROPERTY_GETSET(float, LeverageOnBodyB);

			internal:
				HK_DERIVED_CLASS_INTERNALS(HkpPulleyConstraintAtom, hkpPulleyConstraintAtom, HkpConstraintAtom)
			};

			/*public ref class HkpPulleyConstraintInfo sealed {
			public:
				HkpPulleyConstraintInfo();
				DECLARE_PROPERTY_GETSET(HkVector4^, PositionA);
				DECLARE_PROPERTY_GETSET(HkVector4^, PositionB);
				DECLARE_PROPERTY_GETSET(HkVector4^, PulleyPivotA);
				DECLARE_PROPERTY_GETSET(HkVector4^, PulleyPivotB);
				DECLARE_PROPERTY_GETSET(float, RopeLength);
				DECLARE_PROPERTY_GETSET(float, LeverageOnBodyB);

			internal:
				HK_CLASS_INTERNALS(HkpPulleyConstraintInfo, hkpPulleyConstraintInfo)
			};*/

			public ref class HkpRagdollMotorConstraintAtom : public HkpConstraintAtom {
			public:
				HkpRagdollMotorConstraintAtom();
				Havok4Xna::Physics::Dynamics::HkpConstraintMotor ^GetMotor(int motorNum);
				DECLARE_PROPERTY_GETSET(bool, IsEnabled);
				DECLARE_PROPERTY_GETSET(hkInt16, InitializedOffset);
				DECLARE_PROPERTY_GETSET(hkInt16, PreviousTargetAnglesOffset);
				DECLARE_COMPLEX_PROPERTY_GETSET(HkMatrix3, TargetFrameAinB);

			internal:
				HK_DERIVED_CLASS_INTERNALS(HkpRagdollMotorConstraintAtom, hkpRagdollMotorConstraintAtom, HkpConstraintAtom)
			};

			public ref class HkpSetLocalRotationsConstraintAtom : public HkpConstraintAtom {
			public:
				HkpSetLocalRotationsConstraintAtom();
				DECLARE_COMPLEX_PROPERTY_GETSET(HkRotation, RotationA);
				DECLARE_COMPLEX_PROPERTY_GETSET(HkRotation, RotationB);

			internal:
				HK_DERIVED_CLASS_INTERNALS(HkpSetLocalRotationsConstraintAtom, hkpSetLocalRotationsConstraintAtom, HkpConstraintAtom)
			};

			public ref class HkpSetLocalTransformsConstraintAtom : public HkpConstraintAtom {
			public:
				HkpSetLocalTransformsConstraintAtom();
				DECLARE_COMPLEX_PROPERTY_GETSET(HkTransform, TransformA);
				DECLARE_COMPLEX_PROPERTY_GETSET(HkTransform, TransformB);

			internal:
				HK_DERIVED_CLASS_INTERNALS(HkpSetLocalTransformsConstraintAtom, hkpSetLocalTransformsConstraintAtom, HkpConstraintAtom)
			};

			public ref class HkpSetLocalTranslationsConstraintAtom : public HkpConstraintAtom {
			public:
				HkpSetLocalTranslationsConstraintAtom();
				DECLARE_COMPLEX_PROPERTY_GETSET(HkVector4, TranslationA);
				DECLARE_COMPLEX_PROPERTY_GETSET(HkVector4, TranslationB);

			internal:
				HK_DERIVED_CLASS_INTERNALS(HkpSetLocalTranslationsConstraintAtom, hkpSetLocalTranslationsConstraintAtom, HkpConstraintAtom)
			};

			public ref class HkpSimpleConstraintInfo sealed : public INativeReference {
			public:
				HkpSimpleConstraintInfo();
				DECLARE_PROPERTY_GETSET(float, Mass00);
				DECLARE_PROPERTY_GETSET(float, InvDetM12);
				DECLARE_COMPLEX_PROPERTY_GETSET(HkRotation, Base);
				DECLARE_COMPLEX_PROPERTY_GETSET(HkMatrix3, InvMassMatrix);
				DECLARE_COMPLEX_PROPERTY_GETSET(HkMatrix3, MassMatrix);

			internal:
				HK_CLASS_INTERNALS(HkpSimpleConstraintInfo, hkpSimpleConstraintInfo)
			};

			ref class HkpSurfaceConstraintInfo;

			public ref class HkpSimplexSolverInput sealed : public INativeReference {
			public:
				HkpSimplexSolverInput();
				DECLARE_COMPLEX_PROPERTY_GETSET(HkVector4, Position);
				DECLARE_COMPLEX_PROPERTY_GETSET(HkVector4, Velocity);
				DECLARE_COMPLEX_PROPERTY_GETSET(HkVector4, MaxSurfaceVelocity);
				DECLARE_COMPLEX_PROPERTY_GETSET(HkVector4, UpVector);
				DECLARE_PROPERTY_GETSET(float, DeltaTime);
				DECLARE_PROPERTY_GETSET(float, MinDeltaTime);
				/*DECLARE_PROPERTY_GETSET(HkpSurfaceConstraintInfo^, Constraints);*/
				DECLARE_PROPERTY_GETSET(int, NumConstraints);

			internal:
				HK_CLASS_INTERNALS(HkpSimplexSolverInput, hkpSimplexSolverInput)
			};

			ref class HkpSurfaceConstraintInteraction;

			public ref class HkpSimplexSolverOutput sealed : public INativeReference {
			public:
				HkpSimplexSolverOutput();
				DECLARE_COMPLEX_PROPERTY_GETSET(HkVector4, Position);
				DECLARE_COMPLEX_PROPERTY_GETSET(HkVector4, Velocity);
				DECLARE_PROPERTY_GETSET(float, DeltaTime);
				/*DECLARE_PROPERTY_GETSET(HkpSurfaceConstraintInteraction^, PlaneInteractions);*/

			internal:
				HK_CLASS_INTERNALS(HkpSimplexSolverOutput, hkpSimplexSolverOutput)
			};

			public ref class HkpStiffSpringConstraintAtom : public HkpConstraintAtom {
			public:
				HkpStiffSpringConstraintAtom();
				DECLARE_PROPERTY_GETSET(float, Length);

			internal:
				HK_DERIVED_CLASS_INTERNALS(HkpStiffSpringConstraintAtom, hkpStiffSpringConstraintAtom, HkpConstraintAtom)
			};

			public ref class HkpSurfaceConstraintInfo sealed : public INativeReference {
			public:
				HkpSurfaceConstraintInfo();
				DECLARE_COMPLEX_PROPERTY_GETSET(HkVector4, Plane);
				DECLARE_COMPLEX_PROPERTY_GETSET(HkVector4, Velocity);
				DECLARE_PROPERTY_GETSET(float, StaticFriction);
				DECLARE_PROPERTY_GETSET(float, ExtraUpStaticFriction);
				DECLARE_PROPERTY_GETSET(float, ExtraDownStaticFriction);
				DECLARE_PROPERTY_GETSET(float, DynamicFriction);
				DECLARE_PROPERTY_GETSET(int, Priority);

			internal:
				HK_CLASS_INTERNALS(HkpSurfaceConstraintInfo, hkpSurfaceConstraintInfo)
			};

			public ref class HkpSurfaceConstraintInteraction sealed : public INativeReference {
			public:
				enum class HkpStatus : int {
					OK = hkpSurfaceConstraintInteraction::HK_STATUS_OK,
					_3DFailure = hkpSurfaceConstraintInteraction::HK_STATUS_3D_FAILURE,
					_2DFailure = hkpSurfaceConstraintInteraction::HK_STATUS_2D_FAILURE
				};

				HkpSurfaceConstraintInteraction();
				DECLARE_PROPERTY_GETSET(System::Byte, Touched);
				DECLARE_PROPERTY_GETSET(System::Byte, Stopped);
				DECLARE_PROPERTY_GETSET(float, SurfaceTime);

			internal:
				HK_CLASS_INTERNALS(HkpSurfaceConstraintInteraction, hkpSurfaceConstraintInteraction)
			};

			public ref class HkpTwistLimitConstraintAtom : public HkpConstraintAtom {
			public:
				HkpTwistLimitConstraintAtom();
				DECLARE_PROPERTY_GETSET(System::Byte, IsEnabled);
				DECLARE_PROPERTY_GETSET(System::Byte, TwistAxis);
				DECLARE_PROPERTY_GETSET(System::Byte, RefAxis);
				DECLARE_PROPERTY_GETSET(float, MinAngle);
				DECLARE_PROPERTY_GETSET(float, MaxAngle);
				DECLARE_PROPERTY_GETSET(float, AngularLimitsTauFactor);

			internal:
				HK_DERIVED_CLASS_INTERNALS(HkpTwistLimitConstraintAtom, hkpTwistLimitConstraintAtom, HkpConstraintAtom)
			};

			public ref class HkpVehicleFrictionSolverAxleParams sealed : public INativeReference {
			public:
				HkpVehicleFrictionSolverAxleParams();
				void Initialize();
				DECLARE_PROPERTY_GETSET(float, SlipVelocityFactor);

			internal:
				HK_CLASS_INTERNALS(HkpVehicleFrictionSolverAxleParams, hkpVehicleFrictionSolverAxleParams)
			};

			public ref class HkpVehicleFrictionSolverParams sealed : public INativeReference {
			public:
				HkpVehicleFrictionSolverParams();
				/*HkpVehicleFrictionSolverAxleParams ^GetAxleParam(int index);
				void SetAxleParam(int index, HkpVehicleFrictionSolverAxleParams ^param);*/

				DECLARE_PROPERTY_GETSET(float, MaxVelocityForPositionalFriction);
				DECLARE_COMPLEX_PROPERTY_GETSET(HkpVelocityAccumulator, Chassis);
				DECLARE_COMPLEX_PROPERTY_GETSET(HkpVelocityAccumulator, ChassisAtLastIntegration);

			internal:
				HK_CLASS_INTERNALS(HkpVehicleFrictionSolverParams, hkpVehicleFrictionSolverParams)
			};

			public ref class HkpVelocityAccumulator : public INativeReference {
			public:
				enum class HkpAcculmulatorType : int {
					RigidBody = hkpVelocityAccumulator::HK_RIGID_BODY,
					KeyframedRigidBody = hkpVelocityAccumulator::HK_KEYFRAMED_RIGID_BODY,
					NoGravityRigidBody = hkpVelocityAccumulator::HK_NO_GRAVITY_RIGID_BODY
				};

				HkpVelocityAccumulator();
				void SetFixed();

				DECLARE_PROPERTY_GETSET(bool, MatrixIsIdentity);
				DECLARE_PROPERTY_GETSET(hkUint32, DeactivationClass);
				DECLARE_COMPLEX_PROPERTY_GETSET(HkVector4, LinearVel);
				DECLARE_COMPLEX_PROPERTY_GETSET(HkVector4, AngularVel);
				DECLARE_COMPLEX_PROPERTY_GETSET(HkVector4, InvMasses);

				DECLARE_COMPLEX_PROPERTY_GETSET(HkVector4, CenterOfMassInWorld);
				DECLARE_COMPLEX_PROPERTY_GETSET(HkRotation, CoreFromWorldMatrix);
				DECLARE_COMPLEX_PROPERTY_GETSET(HkVector4, SumLinearVel);
				DECLARE_COMPLEX_PROPERTY_GETSET(HkVector4, SumAngularVel);

			internal:
				HK_CLASS_INTERNALS(HkpVelocityAccumulator, hkpVelocityAccumulator)
			};
		}
	}
}
